<?php
/**
 * Created by PhpStorm.
 * User: lzhy@lzhy.me
 * Date: 2019/4/12 0012
 * Time: 15:26
 */
namespace app\admin\logic;

use Hashids\Hashids;
use think\Db;
use think\facade\Request;
use think\facade\Session;

class Auth
{
    /**
     * 检测登录
     * @return bool|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function checkLogin()
    {
        $userId = session('userId');
        if($userId){
            return true;
        }
        
        $hId = cookie('rememberId');
        $hashIds = new Hashids('i',10);
        $userId  = $hashIds->decode($hId);
        if($userId){
            $userInfo = self::getLoginUserInfoById($userId);
            if($userInfo){
                session('userId',$userInfo['id']);
                session('user',$userInfo);
                return true;
            }
        }

        return false;
    }

    /**
     * 根据id查询用户信息
     * @param $userId
     * @return array|null|\PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getLoginUserInfoById($userId)
    {
        $userInfo = Db::table('user')
            ->field('id,name,avatar,username,role,permission')
            ->where('id','=',$userId)
            ->where('is_delete','=',0)
            ->cache(60)
            ->find();

        return $userInfo;
    }

    /**
     * 登录
     * @param $username
     * @param $password
     * @param bool $remember
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function attempt($username,$password,$remember = false)
    {
        $userInfo = Db::table('user')
            ->field('id,name,avatar,username,password,role,permission')
            ->where('username','=',$username)
            ->where('is_delete','=',0)
            ->find();

        if($userInfo && password_verify($password,$userInfo['password'])){
            unset($userInfo['password']);
            session('userId',$userInfo['id']);
            session('user',$userInfo);
            if($remember){
                $hashIds = new Hashids('i',10);
                $hId = $hashIds->encode($userInfo['id']);
                cookie('rememberId',$hId);
            }
            Session::flash('intoMsg','欢迎您，'.$userInfo['name']);
            self::_updateLoginInfo($userInfo['id']);
            return true;
        }

        return false;
    }

    /**
     * 更新登录信息
     * @param $id
     */
    private static function _updateLoginInfo($id)
    {
        try{
            $data = [
                'last_login_time' => date('Y-m-d H:i:s'),
                'last_login_ip'   => Request::ip()
            ];
            Db::table('user')->where('id','=',$id)->update($data);
        }catch (\Exception $e){

        }
    }

    /**
     * 检测权限
     * @param $user
     * @return bool
     */
    public static function checkAuth($user)
    {
        $userPermission = self::userPermission($user);
        if(!in_array('ANY.*',$userPermission)){
            $requestPath   = strtolower(Request::controller().'/'.Request::action());
            $requestMethod = strtoupper(Request::method());
            $allPermissionMethodMap = self::_permission();

            $_rPermission = [$requestMethod.'.'.$requestPath,'ANY.'.$requestPath];
            if(in_array($_rPermission[0],$allPermissionMethodMap) || in_array($_rPermission[1],$allPermissionMethodMap)){
                if(!in_array($_rPermission[0],$userPermission) && !in_array($_rPermission[1],$userPermission)){
                    return false;
                }
            }
        }
        
        return true;
    }

    /**
     * 当前用户拥有权限
     * @param $user
     * @return array
     */
    public static function userPermission($user)
    {
        $role = Db::table('role')
            ->field('id,auth')
            ->where('id','in',explode(',',$user['role']))
            ->where('is_delete',0)
            ->cache(10)
            ->select();

        $permission = $user['permission'];
        if($role){
            $permission = join(',',array_column($role,'auth')).','.$user['permission'];
        }

        $permissionList = Db::table('permission')
            ->field('id,method,path')
            ->where('is_delete',0)
            ->where('id','in',$permission)
            ->cache(10)
            ->select();

        $allPermissionMethodMap = self::_permissionFormat($permissionList);

        return $allPermissionMethodMap;
    }

    /**
     * 存在的权限
     * @return array
     */
    private static function _permission()
    {
        $permissionList = Db::table('permission')
            ->field('id,method,path')
            ->where('is_delete',0)
            ->cache(10)
            ->select();

        $allPermissionMethodMap = self::_permissionFormat($permissionList);

        return $allPermissionMethodMap;
    }

    private static function _permissionFormat($list)
    {
        $allPermissionMethodMap = [];
        foreach ($list as $v){
            $pathList = explode(',',$v['path']);
            $methodList = ['ANY'];
            if($v['method']){
                $methodList = explode(',',$v['method']);
            }
            foreach ($pathList as $pv){
                foreach ($methodList as $mv){
                    $allPermissionMethodMap[] = $mv.'.'.$pv;
                }
            }
        }

        return $allPermissionMethodMap;
    }
}